package bangry.chat.server.control;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Enumeration;
import java.util.StringTokenizer;
import java.util.Vector;

import bangry.chat.server.ui.ServerMonitor;

// 채팅서버에 연결한  클라이언트와 통신을 위한 스레드
// 채팅서버 관점에서 보면 연결된 하나의 클라이언트를 의미
public class ConnectionChatClient extends Thread {

	private ChatManager chatManager;
	
	private ChatRoom currentRoom;
	
	private Socket clientSocket;
	private BufferedReader in;
	private PrintWriter out;

	int pNo;
	String clientIP;
	String nickName;
	String clientMessage;

	public ConnectionChatClient(Socket clientSocket) {
		this.clientSocket = clientSocket;
		clientIP = clientSocket.getInetAddress().getHostAddress();
		try {
			in = new BufferedReader(new InputStreamReader(clientSocket
					.getInputStream()));
			out = new PrintWriter(clientSocket.getOutputStream(), true);
		} catch (IOException e) {
			e.printStackTrace();
		}
		chatManager = ChatManager.getInstance();
		
	}

	public String getClientIP() {
		return clientIP;
	}

	public void setClientIP(String clientIP) {
		this.clientIP = clientIP;
	}

	public String getNickName() {
		return nickName;
	}

	public void setNickName(String nickName) {
		this.nickName = nickName;
	}

	private void listeningClientMessage() {
		// ServerMonitor.getInstance().addClientList(clientIP, "유저명");

		// 연결된 클라이언트와 데이터를 송수신하기 위해
		// Socket과의 입출력 스트림 생성

		try {
			// 클라이언트가 연결되어 있는 상태이면 무한 메시지 수신 및 전송
			while (clientSocket.isConnected()) {
				clientMessage = in.readLine();
				System.out.println("클라이언트 통메시지:"+clientMessage);

				StringTokenizer st = new StringTokenizer(clientMessage, "||");

				pNo = Integer.parseInt(st.nextToken());
				nickName = st.nextToken();

				// 프로토콜 별 분기
				switch (pNo) {				
				// 대기실 입장메시지
				case 1000:
					// 대기실로 이동
					currentRoom = chatManager.searchChatRoom("대기실");
					currentRoom.enterChatRoom(nickName, this);					
					
					// 서버모니터링창과 리스트창에 클라이언트 입장 출력
					ServerMonitor.getInstance().appendMessage(
							"★★★ [" + nickName + "]님이 ["+currentRoom.getRoomName()+"]에 입장하였습니다 ★★★");
					ServerMonitor.getInstance().addClientList(nickName + " [" + clientIP + "]");

					// 대기실에 클라이언트 대기실 입장 메시지 전송(1000||대화명)
					currentRoom.sendAllMessage(clientMessage);
					// 대기실에 대기 클라이언트 목록 정보 전송(1001||대화명/대화명)
					currentRoom.sendAllMessage("1001||"+currentRoom.getChatClientList());
					// 대기실에 대화방 목록 정보 전송(1002||대화방/대화방)
					currentRoom.sendAllMessage("1002||"+chatManager.getChatRoomList());
					break;

				// 대기실 퇴장메시지
				case 1100:
					// 대기실에서 제거
					currentRoom.leavingChatRoom(nickName);
					
					// 접속클라이언트에서 제거
					chatManager.removeChatClient(this);
					
					// 서버모니터링창과 리스트창에 클라이언트 퇴장 출력
					ServerMonitor.getInstance().appendMessage(
							"＠＠＠ [" + nickName + "]님이 ["+currentRoom.getRoomName()+"]에서 퇴장하였습니다 ＠＠＠");
					ServerMonitor.getInstance().removeClientList(clientIP,
							nickName);
					
					// 대기실에 클라이언트 대기실 퇴장 메시지 전송(1100||대화명)
					currentRoom.sendAllMessage(clientMessage);
					
					// 대기실에 대기 클라이언트 목록 정보 갱신(1001||대화명/대화명)
					currentRoom.sendAllMessage("1001||"+currentRoom.getChatClientList());
										
					return;

				// 다중채팅메시지
				case 2000:
					String chatMessage = st.nextToken();
					// 서버모니터링창과 리스트창에 클라이언트 입장 출력
					ServerMonitor.getInstance().appendMessage(
							"[" + nickName + "] : " + chatMessage);

					currentRoom.sendAllMessage(clientMessage);
					break;
				// 쪽지메시지
				case 2100:
					String receiveNickName = st.nextToken();
					String receiveMessage = st.nextToken();

					// 서버모니터링창에 출력
					ServerMonitor.getInstance().appendMessage(
							"※" + nickName + "님이 " + receiveNickName
									+ "님에 보내는 쪽지내용: " + receiveMessage);

					chatManager.sendMemo(nickName, receiveNickName, receiveMessage);
					break;
				}
				
			}

		} catch (IOException e) {
			// e.printStackTrace();
		} finally {
			try {
				if (clientSocket != null) {
					clientSocket.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}

	public void run() {
		listeningClientMessage();

	}

	// 해당 클라이언트에 메시지 전송
	public void sendMessage(String message) {
		out.println(message);
	}	

}
